package my.mall.service.impl;

import lombok.extern.slf4j.Slf4j;
import my.mall.common.enums.VoEnum;
import my.mall.common.pojo.bo.LoginBo;
import my.mall.common.pojo.bo.RegisterBo;
import my.mall.common.pojo.vo.LoginVo;
import my.mall.common.pojo.vo.ReturnVo;
import my.mall.dao.UserRepository;
import my.mall.entity.User;
import my.mall.service.UserService;
import my.mall.util.JwtUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * <p>
 * 会员表 服务实现类
 * </p>
 *
 * @author fengbo
 * @since 2021-01-14
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public User getUserById(Long id) {
        Optional<User> optional = userRepository.findById(id);
        if (optional.isPresent()) {
            return optional.get();
        }
        throw new IllegalStateException("Get user param error");
    }

    @Override
    public ReturnVo<LoginVo> login(LoginBo loginBo) {
        String username = loginBo.getUsername();
        String password = loginBo.getPassword();
        User user = userRepository.getUserByUserName(username);
        if (user == null) {
            return ReturnVo.warning(VoEnum.LOGIN_FAIL);
        }
        String pwd = DigestUtils.sha256Hex(password);
        if (!pwd.equals(user.getPassword())) {
            return ReturnVo.warning(VoEnum.LOGIN_FAIL);
        }
        LoginVo loginVo = new LoginVo();
        loginVo.setId(user.getId())
                .setUsername(username).setToken(JwtUtils.createToken(username));
        return ReturnVo.success(loginVo);
    }

    /**
     * 非幂等，目前是通过数据库的唯一性约束来保证用户名不重复
     * @param registerBo 注册的参数
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public ReturnVo<LoginVo> register(RegisterBo registerBo) {
        String username = registerBo.getUsername();
        boolean isExists = userRepository.existsByUsername(username);
        if (isExists) {
            return ReturnVo.warning(VoEnum.REGISTER_FAIL_REPEAT_USERNAME);
        }
        String pwd = DigestUtils.sha256Hex(registerBo.getPassword());
        User user = new User().setUsername(username).setPassword(pwd);
        userRepository.saveAndFlush(user);
        LoginVo loginVo = new LoginVo();
        loginVo.setId(user.getId())
                .setUsername(username).setToken(JwtUtils.createToken(username));
        return ReturnVo.success(loginVo);
    }
}
